var callStatusDiv;
// 远程音频元素
var remoteAudio;
// 本地音频元素
var localAudio;
const initWebSIP = () => {
  console.log("SIP.js 加载完成");
  callStatusDiv = document.getElementById("callStatus");
  remoteAudio = document.getElementById("remoteAudio");
  localAudio = document.getElementById("localAudio");
};
// 注册sip数据
let register_SIP_state = {};
// 创建事件系统
const eventBus = {
  events: {},
  on(event, callback) {
    if (!this.events[event]) this.events[event] = [];
    this.events[event].push(callback);
  },
  emit(event, data) {
    if (this.events[event]) {
      this.events[event].forEach((callback) => callback(data));
    }
  },
};
// 暴露事件总线到全局
window.busSIP = eventBus;
const logSip = (message) => {
  console.log(`SIP: ${message}`);
};
// 麦克风音频轨道
let localStream = null;
let audioTrack = null;
// SIP 用户代理
let userAgent = null;
let isMuted = false;
let volume = 1.0;
let logs = []; //日志
let error = "";
let registerer = null;
let currentSession = null;
let audioContext = null;
let Nowivitation = null;
var ring = "https://zy-lib.oss-cn-beijing.aliyuncs.com/webrtc/12820.mp3";
var audioSound = null;
// 加载铃声
const playSound = () => {
  var borswer = window.navigator.userAgent.toLowerCase();
  if (borswer.indexOf("ie") >= 0) {
    //IE内核浏览器
    const strEmbed = document.createElement("embed");
    strEmbed.name = "embedPlay";
    strEmbed.src = ring;
    strEmbed.autostart = "true";
    strEmbed.hidden = "true";
    strEmbed.id = "audioPlay";
    strEmbed.loop = "true";
    document.body.appendChild(strEmbed);
    audioSound = document.getElementById("audioPlay");
    embed.volume = 100;
  } else {
    //非IE内核浏览器
    const strAudio = document.createElement("audio");
    strAudio.id = "audioPlay";
    strAudio.src = ring;
    strAudio.hidden = true;
    strAudio.loop = true;
    document.body.appendChild(strAudio);
    audioSound = document.getElementById("audioPlay");
  }
};

// 会话状态变化监听
const setupSessionStateListener = (session) => {
  session.stateChange.addListener((state) => {
    logSip(`会话状态变化: ${state}`);
    switch (state) {
      case SIP.SessionState.Initial:
        callStatusDiv.textContent = "初始化中...";
        break;
      case SIP.SessionState.Establishing:
        callStatusDiv.textContent = "建立连接中...";
        break;
      case SIP.SessionState.Established:
        callStatusDiv.textContent = "通话中...";
        if (session.sessionDescriptionHandler) {
          const remoteStream =
            session.sessionDescriptionHandler.peerConnection.getRemoteStreams()[0];
          if (remoteStream) {
            remoteAudio.srcObject = remoteStream;
            remoteAudio.play().catch((e) => logSip(`自动播放: ${e.message}`));
          }
          const localStream =
            session.sessionDescriptionHandler.peerConnection.getLocalStreams()[0];
          if (localStream) {
            localAudio.srcObject = localStream;
            setupAudioTrack(localStream);
          }
        }
        break;
      case SIP.SessionState.Terminating:
        callStatusDiv.textContent = "正在结束通话...";
        break;
      case SIP.SessionState.Terminated:
        callStatusDiv.textContent = "通话已结束";
        currentSession = null;
        remoteAudio.srcObject = null;
        localAudio.srcObject = null;
        stopAudioMeter();
        audioTrack = null;
        isMuted = false;
        break;
    }
    eventBus.emit("call_status", {
      status: state,
    });
  });
};
// 设置麦克风音频轨道
const setupAudioTrack = (stream) => {
  localStream = stream;
  const audioTracks = stream.getAudioTracks();
  if (audioTracks.length > 0) {
    audioTrack = audioTracks[0];
    isMuted = !audioTrack.enabled;
  } else {
    logSip("警告: 未找到音频轨道");
  }
};
// 设置超时时间
function setTimeEnd(invitation) {
  // 自动拒绝超时（30秒未接听自动拒绝）
  const timeoutId = setTimeout(() => {
    if (
      currentSession === invitation &&
      invitation.state === SIP.SessionState.Initial
    ) {
      logSip("⏰ 来电超时未接听，自动拒绝");
      invitation.reject();
      callStatusDiv.style.display = "none";
      currentSession = null;
    }
  }, 30000);

  // 清理超时计时器
  invitation.stateChange.addListener((state) => {
    if (state !== SIP.SessionState.Initial) {
      clearTimeout(timeoutId);
    }
  });
}

// 创建注册配置参数
const createSipConfiguration = () => {
  const uri = SIP.UserAgent.makeURI(
    `sip:${register_SIP_state.sipUser}@${register_SIP_state.domain}`
  );
  if (!uri) {
    throw new Error("无法创建有效的SIP URI");
  }
  return {
    uri: uri,
    transportOptions: {
      server: register_SIP_state.wsUrl,
      traceSip: true,
    },
    authorizationUsername: register_SIP_state.sipUser,
    authorizationPassword: register_SIP_state.sipPassword,
    sessionDescriptionHandlerFactoryOptions: {
      constraints: { audio: true, video: false },
      //   peerConnectionOptions: {
      //     rtcConfiguration: {
      //       iceServers: [
      //         { urls: "stun:stun.l.google.com:19302" },
      //         { urls: "stun:stun1.l.google.com:19302" },
      //       ],
      //     },
      //   },
      onLocalMediaStream: (stream) => {
        logSip("收到本地媒体流");
        localAudio.srcObject = stream;
        setupAudioTrack(stream);
      },
    },
    delegate: {
      /**
       * 来电处理委托 - 根据SIP.js官方文档实现来电接听功能 <mcreference link="https://sipjs.com/guides/receive-call/" index="0">0</mcreference>
       * @param {SIP.Invitation} invitation - 来电邀请对象
       */
      onInvite: (invitation) => {
        logSip(`收到来电: ${invitation.remoteIdentity.uri.toString()}`);
        // 检查是否已有通话在进行
        if (currentSession) {
          logSip("⚠️ 已有通话正在进行，拒绝新来电");
          invitation.reject();
          return;
        }
        currentSession = invitation;
        Nowivitation = invitation;
        setupSessionStateListener(invitation);
        // 显示来电界面
        const caller = invitation.remoteIdentity.uri.toString();
        callStatusDiv.textContent = `来电: ${caller}`;
        callStatusDiv.style.display = "block";
        eventBus.emit("call_status", {
          status: "incoming",
          caller,
        });
        // 播放来电提示音
        audioSound.play();
        // 接听来电
        setTimeEnd(invitation);
      },
    },
  };
};
// 停止音频计量
const stopAudioMeter = () => {
  if (audioContext && audioContext.state !== "closed") {
    audioContext.close();
    audioContext = null;
  }
};
// 注册sip
const register_SIP = (data) => {
  register_SIP_state = data;
  try {
    navigator.mediaDevices.getUserMedia({ audio: true }).then((stream) => {
      setupAudioTrack(stream);
      logSip("麦克风权限已获取");
      const configuration = createSipConfiguration();
      userAgent = new SIP.UserAgent(configuration);
      userAgent
        .start()
        .then(() => {
          logSip("UserAgent已启动");
          registerer = new SIP.Registerer(userAgent);

          logSip("发送注册请求");
          registerer
            .register()
            .then(() => {
              logSip("注册请求已发送");
            })
            .catch((error) => {
              logSip(`注册失败: ${error.message}`);
            });
          registerer.stateChange.addListener((state) => {
            eventBus.emit("register_status", state);
          });
        })
        .catch((error) => {
          logSip(`UserAgent启动失败: ${error.message}`);
        });
    });
  } catch (error) {
    console.log(error);
    return error;
  }
};
// 注销sip
const unregister_SIP = () => {
  if (registerer) {
    registerer
      .unregister()
      .then(() => {
        logSip("注销请求已发送");
      })
      .catch((error) => {
        logSip(`注销失败: ${error.message}`);
      });
    registerer.stateChange.addListener((state) => {
      eventBus.emit("register_status", state);
    });
  }
};
// 拨打电话
const makeCall_SIP = (data) => {
  if (!userAgent) {
    console.error("请先注册SIP账号");
    return;
  }
  // 要拨打的号码
  const targetNumber = data.targetNumber;
  // 外显号码
  const displayCalledNum = data.displayCalledNum || "";
  const customData = data.customData || "default";
  if (!targetNumber) {
    console.error("请输入要拨打的号码");
    return;
  }
  const targetURI = SIP.UserAgent.makeURI(
    `sip:${targetNumber}@${register_SIP_state.domain}`
  );
  if (!targetURI) {
    throw new Error("无法创建目标SIP URI");
  }
  callStatusDiv.textContent = `正在呼叫 ${targetNumber}...`;
  callStatusDiv.style.display = "block";
  // ✅ 关键：配置 Inviter 以支持早期媒体
  const inviter = new SIP.Inviter(userAgent, targetURI, {
    extraHeaders: [
      `X-Display-Called-Num: ${displayCalledNum}`,
      `X-Data2: ${customData}`,
    ],
    sessionDescriptionHandlerOptions: {
      constraints: { audio: true, video: false },
      // ✅ 核心：处理所有远程流（包括早期媒体）
      onStream: (stream) => {
        logSip("✅ 收到远程媒体流（可能是早期媒体或正式通话）");
        remoteAudio.srcObject = stream;
        // 尝试播放（即使未接通，浏览器允许用户交互后播放）
        remoteAudio.play().catch((error) => {
          logSip(`⚠️ 自动播放失败（可能被浏览器阻止）: ${error.message}`);
          // 可选：提示用户点击页面以启用声音
        });
      },
      onLocalMediaStream: (stream) => {
        logSip("收到本地媒体流");
        localAudio.srcObject = stream;
        setupAudioTrack(stream);
      },
    },
  });
  currentSession = inviter;
  setupSessionStateListener(inviter);

  // 发起呼叫
  inviter
    .invite()
    .then(() => {
      logSip("✅ INVITE 请求已发送");
      logSip(
        `   携带自定义头: X-Display-Called-Num=${displayCalledNum}, X-Data2=${customData}`
      );
      // 此时如果服务器返回 183 + SDP，onStream 会自动触发
    })
    .catch((error) => {
      logSip(`❌ 呼叫失败: ${error.message}`);
      callStatusDiv.textContent = `呼叫失败: ${error.message}`;
      //   hangupBtn.disabled = true;
      currentSession = null;
    });
};
// 挂断电话
const hangupCall_SIP = () => {
  if (!currentSession) {
    logSip("无活动会话");
    return;
  }
  const state = currentSession.state;
  let hangupPromise = null;
  if (
    state === SIP.SessionState.Established ||
    state === SIP.SessionState.Terminating
  ) {
    logSip("正在挂断已接通的通话...");
    hangupPromise = currentSession.bye();
  } else if (state === SIP.SessionState.Establishing) {
    logSip("正在取消未接通的呼叫...");
    hangupPromise = currentSession.cancel();
  } else {
    logSip(`⚠️ 当前状态 ${state}，无法挂断，直接清理`);
    hangupPromise = Promise.resolve();
  }

  hangupPromise
    .catch((error) => {
      logSip(`操作失败: ${error.message}`);
      showError(`操作失败: ${error.message}`);
    })
    .finally(() => {
      // 统一清理
      callStatusDiv.textContent = "通话已结束";
      callStatusDiv.style.display = "block";
      remoteAudio.srcObject = null;
      localAudio.srcObject = null;
      stopAudioMeter();
      audioTrack = null;
      isMuted = false;
      currentSession = null;
    });
};
// 切换静音
const toggleMute_SIP = () => {
  if (!audioTrack) {
    logSip("麦克风未就绪，请先建立通话");
    return;
  }
  isMuted = !isMuted;
  audioTrack.enabled = !isMuted;
};
// 接听来电
const answerCall_SIP = () => {
  audioSound.pause();
  if (!Nowivitation) {
    logSip("❌ 没有来电可以接听");
    return;
  }
  const answerOptions = {
    sessionDescriptionHandlerOptions: {
      constraints: { audio: true, video: false },
      onStream: (stream) => {
        logSip("🎵 收到远程媒体流");
        remoteAudio.srcObject = stream;
        remoteAudio.play().catch((error) => {
          logSip(`⚠️ 自动播放失败: ${error.message}`);
        });
      },
    },
  };
  Nowivitation.accept(answerOptions)
    .then(() => {
      logSip("✅ 已接听来电");
      callStatusDiv.textContent = "通话中...";
      // 移除接听/拒绝按钮，显示挂断按钮
    })
    .catch((error) => {
      logSip(`❌ 接听失败: ${error.message}`);
      callStatusDiv.textContent = `接听失败: ${error.message}`;
      currentSession = null;
      Nowivitation = null;
    });
};
// 拒绝来电
const rejectCall_SIP = () => {
  audioSound.pause();
  if (!Nowivitation) {
    logSip("❌ 没有来电可以拒绝");
    return;
  }
  Nowivitation.reject()
    .then(() => {
      logSip("✅ 已拒绝来电");
      callStatusDiv.style.display = "none";
      currentSession = null;
      Nowivitation = null;
    })
    .catch((error) => {
      logSip(`❌ 拒绝失败: ${error.message}`);
    })
    .finally(() => {
      Nowivitation = null;
    });
};

(function () {
  if (typeof SIP === "undefined") {
    const script = document.createElement("script");
    script.src = "dist/sip-0.21.2.min.js";
    script.onload = initWebSIP;
    document.head.appendChild(script);
    // 添加音频元素到文档
    setTimeout(() => {
      const remote = document.createElement("audio");
      remote.id = "remoteAudio";
      remote.controls = true;
      remote.autoplay = true;
      remote.style.display = "none";
      document.body.appendChild(remote);
      const local = document.createElement("audio");
      local.id = "localAudio";
      local.controls = true;
      local.autoplay = true;
      local.style.display = "none";
      document.body.appendChild(local);
      playSound();
    }, 0);
  } else {
    initWebSIP();
  }
})();
